<template>
	<swiper class="video-swiper" style="width: 100%; height: calc(100vh - 88rpx);" circular
		@change="swiperChange" :current="state.current" :vertical="true" duration="800">
		<swiper-item v-for="(item, index) in state.displaySwiperList" :key="index">
			<view class="swiper-item" @click="handleClick"
				style="width: 100%; height: calc(100vh - 88rpx);">
				<video :id="`video${index}`" style="width: 100%; height: calc(100vh - 88rpx);"
					:controls="controls" :show-fullscreen-btn="false" :autoplay="false" :loop="loop" @ended="ended"
					@controlstoggle="controlstoggle" @play="onPlay" @error="emits('error')" class="video-player"
					:src="item.videoSrc" v-if="index === 0 || !state.isFirstLoad" :enable-play-gesture="true"
					show-mute-btn vslide-gesture></video>

				<slot :item="item"></slot>
			</view>
		</swiper-item>
	</swiper>
</template>

<script lang="ts" setup>
	import { getCurrentInstance, watch, onMounted, onUnmounted } from "vue";
	import { useState } from './moudle'

	interface IvideoItem {
		src : string;//视频链接
		title : string;
		id : string;
	}
	interface Iprops {
		videoList : Array<IvideoItem>
		loop ?: boolean //是否循环播放一个视频
		controls ?: boolean
		autoplay ?: boolean
		autoChange ?: boolean //是否自动滚动播放
		loadMoreOffsetCount ?: any //滚动加载阈值（即播放到剩余多少个之后触发加载更多
	}

	const emits = defineEmits<{
		(e : 'play', value : Event) : void
		(e : 'error') : void
		(e : 'loadMore') : void
		(e : 'change', {
			index: number,
			detail: any,
		}) : void
		(e : 'controlstoggle', value : any) : void
		(e : 'click', value : Event) : void
		(e : 'ended') : void


	}>();
	const props = withDefaults(defineProps<Iprops>(), {
		videoList: () => [],
		loop: true,
		controls: true,
		autoplay: true,
		autoChange: true,
		loadMoreOffsetCount: () => Number
	})

	const state = useState()

	const initVideoContexts = () => {
		state.videoContexts = [
			uni.createVideoContext("video0", getCurrentInstance()),
			uni.createVideoContext("video1", getCurrentInstance()),
			uni.createVideoContext("video2", getCurrentInstance()),
		];
	};

	const onPlay = (e : Event) => {
		emits("play", e);
	};

	function handleClick(e : Event) {
		state.toggleShow = !state.toggleShow;
		emits("click", e);
	}
	
	function ended() {
		// 自动切换下一个视频
		if (props.autoChange) {
			if (state.displayIndex < 2) {
				state.current = state.displayIndex + 1;
			} else {
				state.current = 0;
			}
		}
		emits("ended");
	}
	
	/**
	 * 初始一个显示的swiper数据
	 * @originIndex  从源数据的哪个开始显示默认0，如从其他页面跳转进来，要显示第n个，这个参数就是他的下标
	 */
	function initSwiperData(originIndex = state.originIndex) {
		const originListLength = state.originList.length; // 源数据长度
		const displayList = [];
		displayList[state.displayIndex] = state.originList[originIndex];
		displayList[state.displayIndex - 1 == -1 ? 2 : state.displayIndex - 1] =
			state.originList[
			originIndex - 1 == -1 ? originListLength - 1 : originIndex - 1
			];
		displayList[state.displayIndex + 1 == 3 ? 0 : state.displayIndex + 1] =
			state.originList[originIndex + 1 == originListLength ? 0 : originIndex + 1];
		state.displaySwiperList = displayList;

		if (state.oid >= state.originList.length) {
			state.oid = 0;
		}
		if (state.oid < 0) {
			state.oid = state.originList.length - 1;
		}
		// 暂停所有视频
		state.videoContexts.map((item : any) => item?.stop());
		setTimeout(() => {
			// 当前视频
			if (props.autoplay) {
				state.videoContexts[state.displayIndex].play()

			}
		}, 600);
		// 数据改变
		emits("change", {
			index: originIndex,
			detail: state.originList[originIndex],
		});
		// 加载更多
		var pCount = state.originList.length - props.loadMoreOffsetCount;
		if (originIndex == pCount) {
			emits("loadMore");
		}
	}
	
	/**
	 * swiper滑动时候
	 */
	function swiperChange(event : any) {
		const { current } = event.detail;
		state.isFirstLoad = false;
		const originListLength = state.originList.length; // 源数据长度
		// 向后滚动
		if (state.displayIndex - current == 2 || state.displayIndex - current == -1) {
			state.originIndex =
				state.originIndex + 1 == originListLength ? 0 : state.originIndex + 1;
			state.displayIndex =
				state.displayIndex + 1 == 3 ? 0 : state.displayIndex + 1;
			state.oid = state.originIndex - 1;
			initSwiperData(state.originIndex);
		}
		// 如果两者的差为-2或者1则是向前滑动
		else if (
			state.displayIndex - current == -2 ||
			state.displayIndex - current == 1
		) {
			state.originIndex =
				state.originIndex - 1 == -1
					? originListLength - 1
					: state.originIndex - 1;
			state.displayIndex =
				state.displayIndex - 1 == -1 ? 2 : state.displayIndex - 1;
			state.oid = state.originIndex + 1;
			initSwiperData(state.originIndex);
		}
		state.toggleShow = true;
	}

	function controlstoggle(e : any) {
		state.showControls = e.detail.show;
		emits("controlstoggle", e);
	}

	watch(
		() => props.videoList,
		() => {
			if (props.videoList?.length) {
				state.originList = props.videoList;
				if (state.isFirstLoad || !state.videoContexts?.length) {
					initSwiperData();
					initVideoContexts();
				}
			}
		},
		{
			immediate: true,
		}
	);

	let loadTimer : any = null;
	onMounted(() => {
		// 为了首次只加载一条视频（提高首次加载性能），延迟加载后续视频
		loadTimer = setTimeout(() => {
			state.isFirstLoad = false;
			clearTimeout(loadTimer);
		}, 3000);
	})
	
	onUnmounted(() => {
		clearTimeout(loadTimer);
	})
</script>

<style lang="scss" scoped>
	.video-swiper {
		width: 100%;
		height: 100%;
		background-color: #000;

		swiper-item {

			.video-player {
				width: 100%;
				height: 100%;
			}
		}
	}
</style>